﻿#define _CRT_SECURE_NO_WARNINGS 1

#include<iostream>
#include<stdlib.h>
#include<assert.h>
using namespace std;

//int main()
//{
//	int a = 0;
//	int& b = a; //引用
//
//	cout << &a << endl;
//	cout << &b << endl;
//
//	return 0;
//}



//typedef struct ListNode
//{
//	int val;
//	struct ListNode* next;
//}ListNode,*PListNode;
	

//cpp引用的玩法
//void PushBack(ListNode*& phead, int x)
////void PushBack(PListNode& phead, int x)
//{
//	ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
//	//...
//	if (phead == NULL)
//	{
//		phead = newnode;
//	}
//	else
//	{
//
//	}
//}
//
//int main()
//{
//	ListNode* plist = NULL;
//	PushBack(plist, 1);
//	PushBack(plist, 2);
//	PushBack(plist, 3);
//	PushBack(plist, 4);
//
//	return 0;
//}


//1.引用必须在定义的地方初始化
//2. 一个变量可以有多个引用
//3. 引用一旦引用一个实体，再不能引用其他实体

//void TestRef()
//{
//	int a = 10;
//	// int& ra;  // 该条语句编译时会出错
//	int& ra = a;
//	int& rra = a;
//	int& rrra = ra;
//	
//	cout << &a << endl;
//	cout << &ra << endl;
//	cout << &rra << endl;
//	cout << &rrra << endl;
//}
//
//int main()
//{
//	TestRef();
//
//	return 0;
//}



//引用做返回值

//传值返回    
//int Count()
//{
//	int n = 0;
//	n++;
//	// ...
//	return n;
//}
//
//int main()
//{
//	int ret = Count();
//
//	return 0;
//}

//传引用返回
//int& Count()
//{
//	int n = 0;
//	n++;
//	// ...
//	return n;
//}
//
//int main()
//{
//	int ret = Count();
//	//这里打印的结果可能是1，也可能是随机值
//	cout << ret << endl;
//
//	return 0;
//}


//int& Count()
//{
//	int n = 0;
//	n++;
//	// ...
//	return n;
//}
//
//int main()
//{
//	int& ret = Count();
//	//这里打印的结果可能是1，也可能是随机值
//	cout << ret << endl;
//	cout << ret << endl; //被覆盖
//
//	return 0;
//}



//int& Add(int a, int b)
//{
//	int c = a + b;
//	return c;
//}
//
//int main()
//{
//	int& ret = Add(1, 2);
//	Add(3, 4);
//	cout << "Add(1, 2) is :" << ret << endl;
//	return 0;
//}
//注意：如果函数返回时，出了函数作用域，如果返回对象还在(还没还给系统)，则可以使用
//引用返回，如果已经还给系统了，则必须使用传值返回。


//传引用传参
//1、提高效率
//2、输出型参数（形参的修改，影响实参）

//传引用返回（出了函数作用域对象还在才可以用）
//1、提高效率
//2、修改返回对象

struct SeqList
{
	int* a;
	int size;
	int capacity;
};



//读取第i个位置的值
//修改第i个位置的值
//C的接口设计

//读取第i个位置的值
int SLAT(struct SeqList* ps, int i)
{
	assert(i < ps->size);
	//...
	return ps->a[i];
}
//修改第i个位置的值
void SLModify(struct SeqList* ps, int i, int x)
{
	assert(i < ps->size);

	//...
	ps->a[i] = x;
}


//CPP的接口设计

//读 or 修改第i个位置的值
//int& SLAT(struct SeqList& ps, int i)
//{
//	assert(i < ps.size);
//	//...
//	return ps.a[i];
//}

//int main()
//{
//	struct SeqList s;
//	//...
//	SLAT(s, 0) = 10;
//	SLAT(s, 0) = 20;
//	SLAT(s, 0) = 30;
//	cout << SLAT(s, 0) << endl;
//	cout << SLAT(s, 1) << endl;
//	cout << SLAT(s, 2) << endl;
//
//	return 0;
//}



////升级成了类
//#define N 10
//struct SeqList
//{
//	//成员函数
//	int& at(int i)
//	{
//		assert(i < N);
//		return a[i];
//	}
//	//成员变量
//	int a[N];
//};
//
//int main()
//{
//	struct SeqList s1;//兼容c的用法
//	SeqList s2;//c++更喜欢这样定义
//
//	for (size_t i = 0; i < N; i++)
//	{
//		s2.at(i) = i;
//	}
//	for (size_t i = 0; i < N; i++)
//	{
//		cout << s2.at(i) << " ";
//	}
//	cout << endl;
//
//	return 0;
//}



//在引用的过程中
//权限可以平移
//权限可以缩小
//权限不能放大

//int main()
//{
//	//a是鲁智深 可以喝酒 可以吃肉 不能杀人
//	//给a取个别名b 叫花和尚 可以喝酒 可以吃肉 可以杀人？
//	
//	//权限的放大
//	const int a = 0;
//	int& b = a;
//
//	return 0;
//}
//
//int main()
//{
//	//权限的平移
//	const int a = 0;
//	const int& b = a;
//
//	return 0;
//}
//
//
//int main()
//{
//	//权限的缩小
//	int a = 0; //a可以修改，可以影响b
//	const int& b = a;
//
//	return 0;
//}

//int main()
//{
//	int i = 0;
//	double& d = i;//临时变量具有常性
//	const double& d = i;
//
//	return 0;
//}



//引用和指针底层是一样的
//int main()
//{
//	int a = 0;
//	int* p1 = &a;
//	int& ref = a;
//	
//	return 0;
//}

//引用就是化了妆的指针